import json
from datetime import datetime

from fastapi import FastAPI, Depends
from fastapi.routing import APIRoute
from starlette.middleware import Middleware
from starlette.requests import Request
from starlette.types  import ASGIApp, Scope, Receive, Send

from src.functest.models import Person_TypedDict, Person_BaseModel, Person_Dataclass
from starlette.middleware.base  import BaseHTTPMiddleware


class CustomHeaderMiddleware:
    def __init__(self, app: ASGIApp):
        self.app  = app

    async def __call__(self, scope: Scope, receive: Receive, send: Send):
        print("============CustomHeaderMiddleware==========")
        if scope["type"] == "http":
            # 复制原始 headers 并修改
            headers = dict(scope["headers"])
            headers[b"x-secret"] = b"dyp"  # 注意：键和值必须是 bytes 类型
            scope["headers"] = list(headers.items())

        await self.app(scope,  receive, send)

app = FastAPI(middleware=[Middleware(CustomHeaderMiddleware)])


class FilteredRoute(APIRoute):
    def get_route_handler(self):
        original_handler = super().get_route_handler()

        async def custom_route_handler(request: Request):
            # 前置过滤
            if request.url.path.startswith("/admin"):
                request.scope["user"] = "filtered_user"
            print("==============Filtered Route===========")
            response = await original_handler(request)

            # 后置过滤
            if "location" in response.headers:
                del response.headers["location"]

            return response

        return custom_route_handler


app.router.route_class = FilteredRoute

class FilterMiddleware(BaseHTTPMiddleware):
    async def dispatch(self, request: Request, call_next):
        # 请求过滤（如去除敏感headers）
        if "x-secret" in request.headers:
            del request.headers["x-secret"]

        print("==============FilterMiddleware===========")
        response = await call_next(request)

        # 响应过滤（如脱敏数据）
        if "password" in response.headers:
            del response.headers["password"]

        return response

app.add_middleware(FilterMiddleware)
@app.get("/")
async def read_request(request: Request):
    return {"header_x_secret": request.headers.get("x-secret")}
def sensitive_data_filter(data: dict):
    # 数据脱敏逻辑
    data["credit_card"] = "****-****-****-"
    return data


@app.post("/payments")
async def create_payment(
        data: dict = Depends(sensitive_data_filter)  # 注入过滤器
):
    return {"processed_data": data}
@app.get("/")
async def read_root():
    # 获取当前时间
    current_time = datetime.now().strftime("%Y-%m-%d  %H:%M:%S")

    # 返回 JSON 响应
    return {
        "message": "Hello, World!",
        "current_time": current_time
    }

@app.get("/dataclass")
async def read_dataclass()->Person_Dataclass:
    user_dataclass: Person_Dataclass = Person_Dataclass(name="Bob", age=25, city="bob@example.com")
    return user_dataclass

@app.put("/dataclass")
async def write_dataclass(personInfo:Person_Dataclass)->str:
    print(personInfo)
    return ("success")

@app.get("/basemodel")
async def read_base_model()->Person_BaseModel:
    # 创建一个字典，包含用户信息
    user_dic = {
        "name":"john",
        "age": 30,
        "email":"john@example.com"
    }
    user_base_model: Person_BaseModel = Person_BaseModel.model_validate_json(json.dumps(user_dic))
    # 或者下面写法
    # user_base_model: Person_BaseModel = Person_BaseModel(name="john", age=30, email="john@example.com")
    return user_base_model

@app.put("/basemodel")
async def write_base_model(personInfo:Person_BaseModel)->str:
    print(personInfo)
    return "success"

@app.get("/typeddict")
async def read_dict()->Person_TypedDict:
    user_typed_dict: Person_TypedDict = {
        "name": "Alice",
        "age": '111',  # 不使用第三方工具其实并不强制检查。
        "is_active": True
    }
    # 或者下面写法
    # user_typed_dict:Person_TypedDict = Person_TypedDict(name="user", age=20, is_active=True)
    return user_typed_dict

@app.put("/typeddict")
async def write_dict(personInf:Person_TypedDict)->str:
    print(personInf)
    return "success"

# Swagger UI host:http://0.0.0.0:8000/docs
# ReDoc UI host:http://0.0.0.0:8000/redoc
if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8000)